<?php
namespace Engine;
/**
 * HTTP response class
 * 
 * @version 0.1
 * @author Sergey Tihonov
 */
class Response
{
	/**
	 * HTTP status code
	 *
	 * @var int default 200
	 */
	protected $_status = 200;
    
    /**
     * HTTP content type
     * 
     * @var string
     */
    protected $_contentType = 'text/html';
    
    /**
     * HTTP response body
     * 
     * @var string
     */
    protected $_body = '';
	
	/**
	 * HTTP response codes and messages
	 *
     * @var array
     */
    protected $_messages = array(
        //Informational 1xx
        100 => '100 Continue',
        101 => '101 Switching Protocols',
        //Successful 2xx
        200 => '200 OK',
        201 => '201 Created',
        202 => '202 Accepted',
        203 => '203 Non-Authoritative Information',
        204 => '204 No Content',
        205 => '205 Reset Content',
        206 => '206 Partial Content',
        //Redirection 3xx
        300 => '300 Multiple Choices',
        301 => '301 Moved Permanently',
        302 => '302 Found',
        303 => '303 See Other',
        304 => '304 Not Modified',
        305 => '305 Use Proxy',
        306 => '306 (Unused)',
        307 => '307 Temporary Redirect',
        //Client Error 4xx
        400 => '400 Bad Request',
        401 => '401 Unauthorized',
        402 => '402 Payment Required',
        403 => '403 Forbidden',
        404 => '404 Not Found',
        405 => '405 Method Not Allowed',
        406 => '406 Not Acceptable',
        407 => '407 Proxy Authentication Required',
        408 => '408 Request Timeout',
        409 => '409 Conflict',
        410 => '410 Gone',
        411 => '411 Length Required',
        412 => '412 Precondition Failed',
        413 => '413 Request Entity Too Large',
        414 => '414 Request-URI Too Long',
        415 => '415 Unsupported Media Type',
        416 => '416 Requested Range Not Satisfiable',
        417 => '417 Expectation Failed',
        422 => '422 Unprocessable Entity',
        423 => '423 Locked',
        //Server Error 5xx
        500 => '500 Internal Server Error',
        501 => '501 Not Implemented',
        502 => '502 Bad Gateway',
        503 => '503 Service Unavailable',
        504 => '504 Gateway Timeout',
        505 => '505 HTTP Version Not Supported'
    );
	
    /**
     * Set HTTP status code
     * 
     * @param int $status 
     * @return \Engine\Response
     */
	public function setStatus($status)
	{
		$this->_status = (int)$status;
        return $this;
	}
    
    /**
     * Set HTTP content type text/html
     * 
     * @return \Engine\Response 
     */
    public function setContentTypeHTML()
    {
        $this->_contentType = 'text/html';
        return $this;
    }
    
    /**
     * Set HTTP content type application/json
     * 
     * @return \Engine\Response 
     */
    public function setContentTypeJSON()
    {
        $this->_contentType = 'application/json';
        return $this;
    }
    
    /**
     * Set HTTP response body
     * 
     * @param string|array $body
     * @param bool $append
     * @return \Engine\Response 
     */
    public function write($body, $append = false)
    {
        if ($append === false) {
            $this->_body = $body;
        } else {
            $this->_body .= $body;
        }
        
        return $this;
    }
    
    /**
     * Send HTTP response
     * 
     * @throws \Exception 
     */
    public function sendResponse($request = null)
    {
        if (in_array($this->_status, $this->_messages) === false) {
            throw new \Exception('HTTP status code is not correct');
        }
        // set status
        $status = sprintf('HTTP/1.1 %s', $this->_messages[$this->_status]);
        header($status);
        
        // set content type
        header('Content-type: ' . $this->_contentType . '; charset=utf-8');
        
        if ($this->_contentType == 'text/html') {
            echo $this->_body;
        } elseif ($this->_contentType == 'application/json') {
            $result = array();
            $result['status'] = $this->_status;
            $result['body'] = $this->_body;
            $result['time'] = array('response' => time());
            if ($request) {
                $result['time']['request'] = $request->serverParam('REQUEST_TIME');
            }
            echo json_encode($result);
        }
       // exit(0);
    }
}
